/**
 * 防抖函数
 * @param {Function} func - 要执行的函数
 * @param {number} delay - 延迟时间（毫秒）
 * @param {boolean} immediate - 是否立即执行
 * @returns {Function}
 */
export const debounce = (func, delay = 300, immediate = false) => {
  let timer = null

  return function(...args) {
    const context = this
    const callNow = immediate && !timer

    clearTimeout(timer)
    timer = setTimeout(() => {
      timer = null
      if (!immediate) {
        func.apply(context, args)
      }
    }, delay)

    if (callNow) {
      func.apply(context, args)
    }
  }
}

/**
 * 节流函数
 * @param {Function} func - 要执行的函数
 * @param {number} delay - 延迟时间（毫秒）
 * @returns {Function}
 */
export const throttle = (func, delay = 300) => {
  let lastTime = 0

  return function(...args) {
    const now = Date.now()
    const remaining = delay - (now - lastTime)

    const context = this

    if (remaining <= 0 || remaining > delay) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }

      lastTime = now
      func.apply(context, args)
    } else if (!timer) {
      timer = setTimeout(() => {
        lastTime = Date.now()
        timer = null
        func.apply(context, args)
      }, remaining)
    }
  }
}

/**
 * 深度防抖（带取消功能）
 * @param {Function} func - 要执行的函数
 * @param {number} delay - 延迟时间（毫秒）
 * @returns {Object} 包含函数和取消方法的对象
 */
export const debounceDeep = (func, delay = 300) => {
  let timer = null

  const debounced = function(...args) {
    const context = this
    clearTimeout(timer)
    timer = setTimeout(() => {
      timer = null
      func.apply(context, args)
    }, delay)
  }

  debounced.cancel = function() {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
  }

  return debounced
}

/**
 * 深度节流（带取消功能）
 * @param {Function} func - 要执行的函数
 * @param {number} delay - 延迟时间（毫秒）
 * @returns {Object} 包含函数和取消方法的对象
 */
export const throttleDeep = (func, delay = 300) => {
  let lastTime = 0
  let timer = null

  const throttled = function(...args) {
    const now = Date.now()
    const context = this
    const remaining = delay - (now - lastTime)

    if (remaining <= 0 || remaining > delay) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }

      lastTime = now
      func.apply(context, args)
    } else if (!timer) {
      timer = setTimeout(() => {
        lastTime = Date.now()
        timer = null
        func.apply(context, args)
      }, remaining)
    }
  }

  throttled.cancel = function() {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
    lastTime = 0
  }

  return throttled
}
